# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""

import logging

from django.conf import settings
from django.contrib import auth
from django.core.cache import caches

from blueapps.account.components.sops_session.forms import AuthenticationForm
from blueapps.account.conf import ConfFixture
from blueapps.account.handlers.response import ResponseHandler
from blueapps.utils import client
from blueapps.account.components.sops_session.models import UserProxy

try:
    from django.utils.deprecation import MiddlewareMixin
except Exception:  # pylint: disable=broad-except
    MiddlewareMixin = object


logger = logging.getLogger("component")
cache = caches["login_db"]


class LoginRequiredMiddleware(MiddlewareMixin):
    def process_view(self, request, view, args, kwargs):
        """
        Login  by two ways
        1. views decorated with 'login_exempt' keyword
        2. User has logged in calling auth.login
        """
        # yanzg 一种绕开当前认证中间件的写法
        if hasattr(request, "is_wechat") and request.is_wechat():
            return None

        if hasattr(request, "is_bk_jwt") and request.is_bk_jwt():
            return None

        if hasattr(request, "is_rio") and request.is_rio():
            return None

        if hasattr(request, "is_sops_jwt") and request.is_sops_jwt():
            return None

        if getattr(view, "login_exempt", False):
            return None

        login_exempt = getattr(view, "login_exempt", False)

        if login_exempt or request.user.is_authenticated:
            return None

        logger.debug("开始SopsSession login require 中间件拦截逻辑")
        # django后台登录放行
        if request.path.startswith('/django_admin'):
            return None
        # 开发模式 Debug 绕开中间件
        # return None


        # user = self.check_token_session(request)
        #先auth backend认证,再auth.login(request, user) 存储session, 似乎is_authenticated会变为True


        if request.user.is_authenticated:
            logger.debug("开始SopsSession request.user.is_authenticated 请求user已认证")
            return None

        handler = ResponseHandler(ConfFixture, settings)

        # check if the user is forbidden
        # user_forbidden, msg = self.is_user_forbidden(request)
        # if user_forbidden:
        #     return handler.build_403_response(msg)

        # return handler.build_401_response(request)
        logger.debug("开始SopsSession response 401 请求未认证返回json data 401")
        return handler.build_sops_session_401_response(request)

    def process_response(self, request, response):
        return response

    # def check_token_session(self, request):
    #
    #
    #     # 我猜是从cookie拿token
    #     # request.COOKIES / POST/META等都为queryDict,支持form（dict())
    #     form = AuthenticationForm(request.COOKIES)
    #     if not form.is_valid():
    #         return None
    #
    #     sops_token = form.cleaned_data["sops_token"]
    #
    #     session_key = request.session.session_key
    #     if session_key:
    #          # 确认 cookie 中的 token 和 cache 中的是否一致
    #          cache_session = cache.get(session_key)
    #          is_match = cache_session and sops_token == cache_session.get("sops_token")
    #          # token session匹配 并且 django session匹配
    #          if is_match and request.user.is_authenticated:
    #             return request.user
    #
    #     return None

    # @staticmethod
    # def is_user_forbidden(request) -> (bool, str):
    #     """
    #     check if the user is forbidden
    #     """
    #     USER_FORBIDDEN_CODE = "1302403"
    #     form = AuthenticationForm(request.COOKIES)
    #     if not form.is_valid():
    #         return False, ""
    #
    #     bk_token = form.cleaned_data["bk_token"]
    #     try:
    #         response = client.bk_login.is_login({"bk_token": bk_token})
    #         if response["result"] is False and str(response["code"]) == USER_FORBIDDEN_CODE:
    #             return True, response["message"]
    #     except Exception as e:
    #         logger.debug(f"check user forbidden error: {e}")
    #     return False, ""
